package scuts.core.classes;
import scuts.core.types.LazyIterator;

using scuts.core.extensions.Ints;
using scuts.core.Lazy;
using scuts.core.Map;
using scuts.core.extensions.LazyIterators;
using scuts.core.Compose;
class Enumeration<T> {
  public function pred (a:T):T {
    return toEnum.compose(function (x) return x-1).compose(fromEnum)(a);
  }
  
  public function succ (a:T):T {
    return toEnum.compose(function (x) return x+1).compose(fromEnum)(a);
  }
  
  public function toEnum (i:Int):T {
    throw "abstract";
    return null;
  }
  
  public function fromEnum (i:T):Int {
    throw "abstract";
    return null;
  }
  public function enumFrom (a:T):LazyIterator<T> {
    
      var cur = fromEnum(a);
      return cur.toLazyInfiniteIterator().map(toEnum);
    
  }
  
  public function enumFromTo (a:T, b:T):LazyIterator<T> {
    return fromEnum(a).toLazyIteratorTo(fromEnum(b)).map(toEnum);
  }
  
  public function enumFromThenTo (a:T, b:T, c:T):LazyIterator<T> {
    return fromEnum(b).toLazyIteratorTo(fromEnum(c)).cons(fromEnum(a)).map(toEnum);
  }
}

